home *** CD-ROM | disk | FTP | other *** search
- ;***********************************************************************
- ;
- ; FINITE IMPULSE RESPONSE FOR DSP-12
- ; Least Mean Squares (LMS) algorithm.
- ;
- ; Based on "LMS Autonotcher/Denoiser" of Jarkko Vuori (OH2LNS)
- ;
- ; Version : 2.2
- ; Fecha : 28/Febrero/1993
- ; Autores : Moises Zafra (EA4QV/EA4MZ) / Fernando Limon (EA8SU/EA4SU)
- ;
- ;***********************************************************************
- include '..\asm\ioequ'
- include '..\asm\intequ'
-
- ;-----------------------------------------------------------------------
- ; Internal equates
- ;-----------------------------------------------------------------------
- IO_D2A equ $FFC0 ;D-to-A data
- IO_A2D equ $FFC4 ;A-to-D data
- IO_FLATCH equ $FFC8 ;filter latch
- IO_8254 equ $FFD0 ;programmable timer
-
- ;-----------------------------------------------------------------------
- ; Maxim filters coefficients
- ;-----------------------------------------------------------------------
- maxcoef
- dc $C0
- dc $F1
- dc $C2
- dc $C3
- dc $F4
- dc $D5
- dc $F6
- dc $C7
- dc $C8
- dc $F9
- dc $CA
- dc $CB
- dc $FC
- dc $DD
- dc $FE
- dc $CF
- ;
-
- lmslen equ 24 ;LMS filter lenght
- buflen equ 8 ;lenght of sample buffer
-
- if notch
- ; Notcher constants
- dlen equ 63 ;Delay line lenght
- beta equ 0.125 ;Adaptation coefficient
- decay equ 0.99915 ;Coefficient decay value
- else
- ; Denoiser constants
- dlen equ 1 ;Delay line lenght
- beta equ 0.1875 ;Adaptation coefficient
- decay equ 0.98047 ;Coefficient decay value
- endif
-
- g equ 0.007 ;Biquad filter scaler
-
- org x:$0
- iirs ds 2
- buffer dsm buflen*4
- dline dsm dlen+lmslen
-
- org y:$0
- iircoef dc -1.880563819/2.0, 0.8990682309/2.0
- dc -1.999905221/2.0, 1.0/2.0
- dsm buflen*4
- lmscoef dsm lmslen
-
- ;-----------------------------------------------------------------------
- ; Interrupt vectors
- ;-----------------------------------------------------------------------
- org p:I_RESET ;Entry point
- jmp main
-
- org p:I_IRQA ;Sample interrupt
- jsr sample
-
-
- ;***********************************************************************
- ; MAIN CODE
- ;***********************************************************************
- org p:$100
- main
-
- ;------------------------------------------------------------------------------
- ; Program the BCR as reqd
- ;------------------------------------------------------------------------------
- movep #>$0003,x:M_BCR ;No waits for memory, 3 for i/o
-
- ;------------------------------------------------------------------------------
- ; NOTE: The 82C54 input clock is 3.9936 MHZ
- ; Program TIMER-0: RX filter clock
- ;------------------------------------------------------------------------------
- movep #>$36,y:IO_8254+3 ;Mode 3, LSB+MSB, binary
- movep #>$14,y:IO_8254+0 ;3,993,600 / 20 = about 200khz
- movep #>$00,y:IO_8254+0
-
- ;------------------------------------------------------------------------------
- ; Program TIME-1: TX filter clock
- ;------------------------------------------------------------------------------
- movep #>$76,y:IO_8254+3 ;Mode 3, LSB+MSB, binary
- movep #>$14,y:IO_8254+1 ;3,993,600 / 20 = about 200khz
- movep #>$00,y:IO_8254+1
-
- ;------------------------------------------------------------------------------
- ; Program TIMER-2: sample clock
- ;------------------------------------------------------------------------------
- movep #>$B4,y:IO_8254+3 ;Mode 2, LSB+MSB, binary
- movep #>$2B,y:IO_8254+2 ;3,993,600 / 555 = about 7.2k samples/sec
- movep #>$02,y:IO_8254+2
-
- ;------------------------------------------------------------------------------
- ; Program the MAXIM filters
- ; Both Filters: Mode=1, FN=3, QN=55
- ;------------------------------------------------------------------------------
- move #>$C0,x0 ;eor bit for both tx and rcv filter
- move #maxcoef,r1
- do #16,end_f
- move x:(r1)+,a1
- movep a1,y:IO_FLATCH
- eor x0,a
- movep a1,y:IO_FLATCH
- eor x0,a
- movep a1,y:IO_FLATCH
- end_f nop
-
- ;------------------------------------------------------------------------------
- ; Init structure for data and arrange for interrupts as reqd
- ;------------------------------------------------------------------------------
- move #<buffer+2,r7 ;Interrupt handler pointer
- move #buflen*4-1,m7
-
- move #<lmscoef,r6 ;LMS filter coeff pointer
-
- move #<iircoef,r5 ;IIR filter coeff pointer
- move #4-1,m5
-
- move #<buffer,r2 ;Sample buffer read pointer
- move #4-1,n2
- move #buflen*4-1,m2
-
- move #dline,r1 ;Delay line sample pointer
- move #dlen+lmslen-1,m1
-
- movep #>$0007,x:M_IPR ;Program IRQ-A to be edge triggered,
- ;level 2
- move #0,sr ;Allow all interrupts
-
- loop jmp loop ;Infinite loop
-
- ;***********************************************************************
- ; INTERRUPT HANDLER
- ;***********************************************************************
- sample
-
- ;-----------------------------------------------------------------------
- ; Read from A/D
- ;-----------------------------------------------------------------------
- movep y:IO_A2D,x0 ; read A/D
- move x0,y:(r2)+
-
- ;-----------------------------------------------------------------------
- ; Highpass filter the input signal (with one biquad IIR section)
- ;-----------------------------------------------------------------------
- ori #$0B,mr ;Set left shift scaling mode
- move #g,x1 ;Scale input signal
- mpy x0,x1,a #<iirs,r0
- nop
-
- move x:(r0)+,x0 y:(r5)+,y0 ;s1, a1
- mac -x0,y0,a x:(r0),x1 y:(r5)+,y0 ;s2, a2
- macr -x1,y0,a x0,x:(r0)- y:(r5)+,y0 ;new s2, get b1
- mac x0,y0,a a,x:(r0) y:(r5)+,y0 ;new s1, get b2
- macr x1,y0,a
- andi #$F4,mr ;Restore scaling mode
-
- move a,x0 ;Back scaling
- move #>@cvi(1.0/g)-5,x1
- mpy x0,x1,a
- asr a
- move a0,x:(r1)+
- move a0,x1
-
- ;-----------------------------------------------------------------------
- ; FIR filter
- ;-----------------------------------------------------------------------
- clr a x:(r1)+,x0 y:(r6)+,y0
- rep #lmslen-1
- mac x0,y0,a x:(r1)+,x0 y:(r6)+,y0
- macr x0,y0,a x:(r1)-,x0 y:(r6)-,y0
-
- ;-----------------------------------------------------------------------
- ; Store FIR output as a program output if denoiser code
- ;-----------------------------------------------------------------------
- if !notch
- move a,y:(r2)+n2
- endif
-
- ;-----------------------------------------------------------------------
- ; Calculate error (e = D - Y) to x1
- ;-----------------------------------------------------------------------
- neg a
- add x1,a
- move a,x1
-
- ;-----------------------------------------------------------------------
- ; Store error as a program output if notcher code
- ;-----------------------------------------------------------------------
- if notch
- move x1,y:(r2)+n2
- endif
-
- ;-----------------------------------------------------------------------
- ; Write to D/A
- ;-----------------------------------------------------------------------
- write
- move a,x0
- move y:(r2)+n2,a
- move #>$800000,y1
- eor y1,a
- neg a
- movep a1,y:IO_D2A
- move x0,a
-
- ;-----------------------------------------------------------------------
- ; Wiener filter adaptation part
- ;-----------------------------------------------------------------------
- move #beta,x0
- move #decay,y1
-
- mpyr x0,x1,a r6,r4 ;x1=beta*e
- move a,x1
-
- move x:(r1)-,x0 y:(r6)-,y0 ;get x(0), c(0)
- mpy y0,y1,a
- macr x0,x1,a x:(r1)-,x0 y:(r6)-,y0 ;c(0)=decay*c(0)
- do #lmslen-1,adaloop ; + e*x(0)
- mpy y0,y1,a a,y:(r4)- ;save new c(0)
- macr x0,x1,a x:(r1)-,x0 y:(r6)-,y0 ;c(n)=decay*c(n)
- adaloop ; + e*x(n)
- move a,y:(r4)- ;save new c(n)
- move x:(r1)+,x0 y:(r6)+,y0
- move x:(r1)+,x0 y:(r6)+,y0
-
- ;-----------------------------------------------------------------------
- rti
-
- end main
-